package com.stars.easyms.security.autoconfigure;

import com.stars.easyms.base.constant.CommonConstants;
import com.stars.easyms.security.constant.EasyMsSecurityConstants;
import com.stars.easyms.security.jwt.EasyMsJWTConfigurer;
import com.stars.easyms.security.jwt.EasyMsJWTProvider;
import com.stars.easyms.security.properties.EasyMsSecurityProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;

/**
 * EasyMsSecurity自动配置类
 *
 * @author guoguifang
 * @date 2020-08-12 17:24
 * @since 1.6.0
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@EnableConfigurationProperties(EasyMsSecurityProperties.class)
public class EasyMsSecurityAutoConfiguration extends WebSecurityConfigurerAdapter {

    private final EasyMsSecurityProperties easyMsSecurityProperties;

    private final EasyMsJWTProvider easyMsJWTProvider;

    public EasyMsSecurityAutoConfiguration(EasyMsSecurityProperties easyMsSecurityProperties) {
        this.easyMsSecurityProperties = easyMsSecurityProperties;
        this.easyMsJWTProvider = new EasyMsJWTProvider(easyMsSecurityProperties);
    }

    @Bean
    public EasyMsJWTProvider easyMsJWTProvider() {
        return this.easyMsJWTProvider;
    }

    @Override
    public void configure(HttpSecurity httpSecurity) throws Exception {
        if (easyMsSecurityProperties.isEnabled()) {

            // 关闭csrf
            httpSecurity.csrf().disable();

            final ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();

            // easyMs相关的url不做权限控制
            EasyMsSecurityConstants.EASY_MS_URL.forEach(s -> registry.antMatchers(s).permitAll());

            // 在配置permit中配置的不做权限控制
            if (!StringUtils.isEmpty(easyMsSecurityProperties.getPermit())) {
                for (String str : StringUtils.tokenizeToStringArray(easyMsSecurityProperties.getPermit(), CommonConstants.PROPERTIES_SEPARATOR)) {
                    registry.antMatchers(str).permitAll();
                }
            }

            // 其他的请求做权限控制
            registry.anyRequest().authenticated().and().apply(securityConfigurerAdapter());
        } else {
            httpSecurity.csrf().disable().authorizeRequests().anyRequest().permitAll().and().logout().permitAll();
        }
    }

    private EasyMsJWTConfigurer securityConfigurerAdapter() {
        return new EasyMsJWTConfigurer(easyMsSecurityProperties, easyMsJWTProvider);
    }

}
